package simulator.src;

import java.util.LinkedList;
import simulator.src.TxRxEvent.TxRxEventType;

public class Transmiter {
	public enum State { IDLE, TX };
	
	double Rb;
	double d;
	static double vp=200000000.0; // vp = 2e8 m/s.
	State state;
	LinkedList<Data> queue;
	
	Transmiter(double binaryRate, double length) {

		Rb = binaryRate;
		d  = length;
		
		queue = new LinkedList<Data>();
		state = State.IDLE;
	}
	
	public void arrivalData(Data data) {
		
		// Output
		String s="";
        s=""+Simulator.getClock()+"\t"+"A"+"\t"+data.getID()+"\t";
        int tx=0;
        if (state==State.TX) tx=1;
        s=s+data.getTimeStamp()+"\t"+Simulator.getClock()+"\t"+"-"+"\t"+"-"+"\t"+"-"+"\t"+queue.size()+"\t"+(queue.size()+tx);
		Simulator.data(s);		
		
        switch( state){
        case IDLE:{
    			startTx(data);
    			state = State.TX;
    			break;
    			}
        case TX:{
	        	queue.addLast(data);
	        	state = State.TX;
	        	break;
        	}
        }
	}
		
	public void startTx(Data data) {
		// Update statistics		
		TxRxSystem.delayQ+=Simulator.getClock()-data.getTimeStamp();
		
		// Output
		String s = "[Transmiter@";
		s=s+Simulator.getClock()+" Start TX Data ID: "+data.getID()+"]";
		Simulator.debug(s);
        s=""+Simulator.getClock()+"\t"+"Stx"+"\t"+data.getID()+"\t";
        s=s+data.getTimeStamp()+"\t"+Simulator.getClock()+"\t"+"-"+"\t"+"-"+"\t"+"-"+"\t"+queue.size()+"\t"+(queue.size()+1);
		Simulator.data(s);		
		
        double tprog = this.d /this.vp;
        double time =Simulator.getClock();
        
        TxRxEvent startRXEvent = new TxRxEvent((time+ tprog), TxRxEventType.StartRX, data);
        Simulator.addEvent(startRXEvent);
        
        double Ttx = data.getSize()/this.Rb;
        TxRxEvent stopTXEvent = new TxRxEvent(time +Ttx	, TxRxEventType.StopTX, data);
        Simulator.addEvent(stopTXEvent);
	}
	
	public void stopTx(Data data) {
		if (state == State.TX) {
			// Update statistics
			TxRxSystem.delayQtx+=Simulator.getClock()-data.getTimeStamp();
								
			// Output
			String s="";
	        s=""+Simulator.getClock()+"\t"+"Etx"+"\t"+data.getID()+"\t";
	        s=s+data.getTimeStamp()+"\t"+"-"+"\t"+Simulator.getClock()+"\t"+"-"+"\t"+"-"+"\t"+queue.size()+"\t"+queue.size();
			Simulator.data(s);	
			s = "[Transmiter@";
			s=s+Simulator.getClock()+" Stop TX Data ID: "+data.getID()+"]";
			Simulator.debug(s);
			
			 double tprog = this.d /this.vp;
	        
	        TxRxEvent stopRXEvent = new TxRxEvent(Simulator.getClock()+tprog	, TxRxEventType.StopRX, data);
	        Simulator.addEvent(stopRXEvent);
	        	
            if(queue.isEmpty()) {
            	state = State.IDLE;
            	
            }
            else {
            	Data datatoSend = queue.removeFirst();
            	startTx(datatoSend);
            	state = State.TX;
            }
			
		} else {
			Simulator.debug("ERROR - not a valid state for action stopTx");
			System.exit(1);
		}
	}
	
}
